package com.ayf.payment.game.api.service.payment;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.channel.jiabei.util.StringHelper;
import com.ayf.payment.game.api.channel.zhuofutong.util.HttpTookit;
import com.ayf.payment.game.api.channel.zhuofutong.util.SignUtils;
import com.ayf.payment.game.api.dto.MerchantCommonDTO;
import com.ayf.payment.game.api.dto.OrderAndMerchantDTO;
import com.ayf.payment.game.api.dto.platform.MerchantPaymentProductDTO;
import com.ayf.payment.game.api.dto.platform.PaymentChannelDTO;
import com.ayf.payment.game.api.entity.Order;
import com.ayf.payment.game.api.entity.Partition;
import com.ayf.payment.game.api.exception.NullSetException;
import com.ayf.payment.game.api.type.OrderStatus;
import com.ayf.payment.game.api.utils.DateUtils;
import com.ayf.payment.game.api.utils.Md5Utils;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author wwl
 * @description:
 * @date 2021/2/22 14:18
 */
@Service
public class ZhuoFuTongPaymentService extends IPaymentService {

    @Override
    public Map<String, Object> paymentUtil(Order order, Partition partition, String orderCreateStr, String traceId, String redirectUrl) {
            Map<String, Object> result = new HashMap<>(3);
            MerchantPaymentProductDTO merchantPaymentProductDTO = systemInitialization.productDTO(order.getPayTypeId());
            PaymentChannelDTO paymentChannelDTO = systemInitialization.channelDTO(merchantPaymentProductDTO.getcId());
            BigDecimal actualOrderAmt = getActualOrderAmt(order.getAmount(),paymentChannelDTO.getId(),partition.getMerchantId());
            MerchantCommonDTO merchantDTO = merchantService.getMerchantCommon(order.getMerchantId());
            String productName = "";
            if (StringUtils.isNotBlank(merchantDTO.getCustomerQq())) {
                productName = merchantDTO.getCustomerQq();
            } else if (StringUtils.isNotBlank(merchantDTO.getQq())) {
                productName = merchantDTO.getQq();
            }
            if (StringUtils.isNotBlank(productName)) {
                productName=String.format("客服QQ:%s MN:%s", productName, order.getMerchantOrderNo());
            } else {
                productName=String.format("MN:%s", order.getMerchantOrderNo());
            }

            String resultCode = orderCreate(order,traceId,paymentChannelDTO,productName,merchantPaymentProductDTO.getBusinessCode(),actualOrderAmt,redirectUrl);
            if (resultCode == null) {
                throw new NullSetException("下单失败，请稍后重试！");
            }
            order.setRandomAmt(BigDecimal.ZERO);
            order.setOrderNo("");
            order.setPayChannleName(paymentChannelDTO.getName());
            order.setPayChannleId(paymentChannelDTO.getId());
            order.setPayTypeId(merchantPaymentProductDTO.getProductId());
            order.setPayTypeName(merchantPaymentProductDTO.getProductName());
            order.setMerchantIncome(BigDecimal.ZERO);
            order.setPlatformIncome(BigDecimal.ZERO);
            order.setFee(BigDecimal.ZERO);
            order.setChannelIncome(BigDecimal.ZERO);
            orderMapper.insertSelective(order);
            result.put("code", "003");
            result.put("RedirectUrl",resultCode);

        return result;
    }

    @Override
    public void queryPayOrder(OrderAndMerchantDTO dto, String traceId) {
        try {
            PaymentChannelDTO paymentChannelDTO = systemInitialization.channelDTO(dto.getPayChannleId());
            String KeyValue = paymentChannelDTO.getChannelKey();
            String orderid=dto.getMerchantOrderNo();
            String resultCode = queryCreate(dto.getMerchantId(), orderid, traceId,paymentChannelDTO);
            if (StringUtils.isEmpty(resultCode)){
                LogPortal.error("{} 卓付通订单查询 商户订单号:{} 支付渠道返回内容为空",traceId,orderid);
                return;
            }
            JSONObject map =JSONObject.parseObject(resultCode);
            String code =map.getString("code");
            OrderStatus orderStatus = OrderStatus.PROCESSING;
            if ("0".equals(code)) {
                String status =map.getString("status");
                String mchOrderNo =map.getString("mchOrderNo");
                String sign =map.getString("sign");
                Map<String, String> dicMap = new HashMap<String, String>();
                dicMap.put("mchOrderNo",mchOrderNo);
                dicMap.put("status",status);
                String signs= SignUtils.sign(dicMap,KeyValue).toUpperCase();
                if (sign.trim().equals(signs)) {
                    Order order = orderService.selectByMerchantOrderNo(orderid);
                    if (order == null) {
                        LogPortal.error("{} 卓付通订单查询 商户订单号:{} 在我方系统查询不到",traceId, orderid);
                        return;
                    }
                    if ("0".equals(status)||"1".equals(status)) {
                         orderStatus = OrderStatus.PROCESSING;
                    }
                    if ("2".equals(status)) {
                        orderStatus = OrderStatus.SUCCESS;
                    }
                    if (OrderStatus.PROCESSING.equals(order.getOrderStatus()) && !orderStatus.equals(OrderStatus.PROCESSING)) {
                        order.setOrderStatus(orderStatus);
                        orderService.paymentOrder(order, new JSONObject());
                        if (OrderStatus.SUCCESS.equals(order.getOrderStatus())) {
                            orderService.orderToGetWay(order);
                            wxSendMsgUtils.rechargeSuccess(order);
                        }
                    }
                } else {
                    LogPortal.error("{} 卓付通订单查询 商户订单号:{} 验签错误 sign[{}] signs[{}]", traceId, orderid,sign,signs);
                }
            }else{
                LogPortal.error("{} 卓付通订单查询 商户订单号:{} 返回失败信息:{}", traceId, orderid,resultCode);
            }
        } catch(Exception e){
            LogPortal.error("{} 卓付通订单查询 商户订单号:{} 发生{}异常", e, dto.getMerchantOrderNo(),e.getClass().getName());
        }

    }

    private String orderCreate(Order order, String traceId, PaymentChannelDTO paymentChannelDTO,String productName,String businessCode, BigDecimal actualOrderAmt,String redirectUrl) {
        String MerhantId =paymentChannelDTO.getAccountNumber();
        String KeyValue = paymentChannelDTO.getChannelKey();
        String AuthorizationURL = paymentChannelDTO.getPaymentUrl();
        String returnUrl=paymentChannelDTO.getReturnUrl();
        if (StringUtils.isEmpty(AuthorizationURL)){
            LogPortal.error("{} 失败，通道下单地址不能为空，订单号:{}",traceId,order.getMerchantOrderNo());
            throw new NullSetException(traceId + "下单失败，请稍后重试！");
        }
        if (!AuthorizationURL.endsWith("/")){
            AuthorizationURL=AuthorizationURL.concat("/");
        }
        AuthorizationURL=AuthorizationURL.concat("api/pay");
        if (!returnUrl.endsWith("/")){
            returnUrl=returnUrl.concat("/");
        }
        if (!redirectUrl.endsWith("/")){
            redirectUrl=redirectUrl.concat("/");
        }

        HashMap<String, String> dicMap = new HashMap<String, String>();
        HashMap<String, String> goodsParamExt = new HashMap<String, String>();
        goodsParamExt.put("goodsName",productName);
        goodsParamExt.put("goodsDesc",productName);
        dicMap.put("amount",String.valueOf(actualOrderAmt));
        dicMap.put("channelCode", getPayCode(businessCode));
        dicMap.put("goodsParamExt", JSON.toJSONString(goodsParamExt));
        dicMap.put("ip",order.getClientIp());
        dicMap.put("mchId", MerhantId);
        dicMap.put("mchOrderNo", order.getMerchantOrderNo());
        dicMap.put("notifyUrl", returnUrl.concat("/gameapip/v/zftong/pay/notify"));
        dicMap.put("returnUrl", redirectUrl.concat("gws/loading.html?orderNo=" + order.getMerchantOrderNo()));
        dicMap.put("serviceName", "com.zhuofutong.api.pay.qrcode");
        dicMap.put("signType", "MD5");
        SortedMap<String, String> sortMap = new TreeMap<String, String>(dicMap);
        String signData = StringHelper.createSign(sortMap);
        String sign = Md5Utils.md5(signData + "key=" + KeyValue);
        dicMap.put("sign", sign);

        SortedMap<String, String> SortParamMap = new TreeMap<String, String>(dicMap);
        //生成请求字符串
        String param = JSON.toJSONString(SortParamMap);

        //生成请求字符串
        LogPortal.info("{} 卓付通下单 商户ID[{}] 商户订单号[{}] 请求参数[{}]", traceId, order.getMerchantId(), order.getMerchantOrderNo(), param);
        String result = "";
        try {
            //请求上游接口
            result = HttpTookit.HttpPostWithJson(AuthorizationURL, param);
            LogPortal.info("{} 卓付通下单 商户ID[{}] 商户订单号[{}] 调用支付渠道下单接口成功，响应报文:{}", traceId, order.getMerchantId(), order.getMerchantOrderNo(), result);
            JSONObject jsonObject = JSONObject.parseObject(result);
            String code=jsonObject.getString("code");
            String url=jsonObject.getString("url");
            String signStr=jsonObject.getString("sign");
            if("0".equals(code)){
                String signResult = Md5Utils.md5("url="+url+ "&key=" + KeyValue).toUpperCase();
                if(signResult.equals(signStr))
                return url;
            }
        } catch (Exception e) {
            LogPortal.error("{} 卓付通下单 PAYMENT_PROGRAM_CHANNEL_ORDER_CREATE_FAIL 商户ID[{}] 商户订单号[{}] 支付程序向支付渠道下单失败，发生了{}异常，错误描述:{}", traceId, order.getMerchantId(), order.getMerchantOrderNo(), e.getClass().getName(), e.getMessage());
            LogPortal.error("{} 卓付通下单 商户ID[{}] 商户订单号[{}] 支付程序向支付渠道下单失败，发生了{}异常，错误描述:{}", e, traceId, order.getMerchantId(), order.getMerchantOrderNo(), e.getClass().getName(), e.getMessage());
        }
        return null;
    }

    private String queryCreate(Integer merId, String orderid, String traceId, PaymentChannelDTO paymentChannelDTO) {
        String result = "";
        try {
            String AuthorizationURL = paymentChannelDTO.getPaymentUrl();
            if (StringUtils.isEmpty(AuthorizationURL)){
                LogPortal.error("{} 失败，通道下单地址不能为空，订单号:{}",traceId,orderid);
                throw new NullSetException(traceId + "下单失败，请稍后重试！");
            }
            if (!AuthorizationURL.endsWith("/")){
                AuthorizationURL=AuthorizationURL.concat("/");
            }
            AuthorizationURL=AuthorizationURL.concat("api/pay");
            String MerhantId = paymentChannelDTO.getAccountNumber();
            String KeyValue = paymentChannelDTO.getChannelKey();
            Map<String, String> dicMap = new HashMap<String, String>();
            dicMap.put("mchId", MerhantId);  //商户号
            dicMap.put("mchOrderNo", orderid);  //商户订单号
            dicMap.put("serviceName","com.zhuofutong.api.pay.query");  //接口类型
            dicMap.put("signType", "MD5");  //签名类型
            String signStr= SignUtils.sign(dicMap,KeyValue);
            dicMap.put("sign", signStr);  //加密
            String param = JSON.toJSONString(dicMap);
            LogPortal.info("{} 卓付通订单查询 商户[{}] 商户订单号[{}] 请求参数[{}]", traceId, merId, orderid, param);
            result = HttpTookit.HttpPostWithJson(AuthorizationURL, param);
            LogPortal.info("{} 卓付通订单查询 商户[{}] 商户订单号[{}] 返回参数[{}]", traceId, merId, orderid, result);
        } catch (Exception e) {
            LogPortal.error("{} 卓付通订单查询失败 商户[{}] 商户订单号[{}] 发生了{}异常，错误描述:{}", e, traceId, merId, orderid, e.getClass().getName(), e.getMessage());
        }
        return result;
    }

    private String getPayCode(String code) {
        if ("ALIPAY".equals(code) || "ANTCREDITPAY".equals(code)) {
            return "ALIPAY";
        } else if ("WECHAT".equals(code)) {
            return "WECHAT";
        } else {
            throw new NullSetException("该通道不支持充值，请更换其他通道充值！");
        }
    }

    static void test_queryPayOrder(){
        PaymentChannelDTO paymentChannelDTO = getTestPaymentChannelDTO();
        String traceId = SnowFlakeUtils.getTraceId();
        Integer merchanId = Integer.valueOf(11);
        ZhuoFuTongPaymentService zhuoFuTongPaymentService =new ZhuoFuTongPaymentService();
        String orderid = "M2207041822993582641536204800";
        zhuoFuTongPaymentService.queryCreate(merchanId,orderid, traceId,paymentChannelDTO);
    }

    static void test_orderCreate(){
        PaymentChannelDTO paymentChannelDTO = getTestPaymentChannelDTO();
        String traceId = SnowFlakeUtils.getTraceId();
        String businessCode = "ALIPAY";
        String redirectUrl = "http://t1gameweb3.potiandao.cn";

        Order order = new Order();
        Date currentDate = DateUtils.getNowDate();
        String orderCreateStr = DateUtils.dateToString(currentDate, DateUtils.formatPattern_full_03);
        String orderNo = "M" + orderCreateStr + SnowFlakeUtils.getUniqueId();
        order.setMerchantOrderNo(orderNo);
        order.setCreateTime(currentDate);
        order.setAmount(BigDecimal.valueOf(1));
        order.setMerchantId(1000);

        String productName =orderNo;

        ZhuoFuTongPaymentService zhuoFuTongPaymentService =new ZhuoFuTongPaymentService();
        String result = zhuoFuTongPaymentService.orderCreate(order,traceId,paymentChannelDTO,productName,businessCode,order.getAmount(),redirectUrl);
        System.out.println("下单返回报文:"+result);
    }

    /**
     * 构造测试请求通道商户参数
     * @return
     */
    private static PaymentChannelDTO getTestPaymentChannelDTO(){
        PaymentChannelDTO paymentChannelDTO = new PaymentChannelDTO();
        paymentChannelDTO.setPaymentUrl("http://zf.zhihaowang888.com");
        paymentChannelDTO.setAccountNumber("1122");
        paymentChannelDTO.setChannelKey("EOOGE8LMW12WWOC8FD5OAC7ZOWPIPI3U");
        paymentChannelDTO.setReturnUrl("http://t1gameweb3.potiandao.cn");
        return paymentChannelDTO;
    }

    public static void main(String[] args) {
        test_queryPayOrder();
//        test_orderCreate();
    }
}
